﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.TestManagement.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using System.Threading;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {

        ITestManagementTeamProject sourceproj;
        ITestManagementTeamProject destinationproj;
        private TfsTeamProjectCollection sourceTFS;
        private TfsTeamProjectCollection destinationTFS;
        private WorkItemStore sourceStore;
        private WorkItemStore destinationStore;
        private Project sourceProject;
        private Project destinationProject;
        private bool migrationChecked = false;
        private bool restoreChecked = false;
        private bool deletePlans = false;
        private bool duplicateSharedSteps = false;
        private bool includeAttachments = false;

        public MainWindow()
        {
            InitializeComponent();
            

            
        }

        private ITestManagementTeamProject GetProject(TfsTeamProjectCollection tfs, string project)
        {

            ITestManagementService tms = tfs.GetService<ITestManagementService>();

            return tms.GetTeamProject(project);
           
            
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            migrationChecked = (bool)MigrateTestSelectionCheckBox.IsChecked;
            restoreChecked = (bool)RestoreTestSelectionCheckBox.IsChecked;
            deletePlans = (bool)DeletePlansCheckBox.IsChecked;
            duplicateSharedSteps = (bool)SharedStepCheckBox.IsChecked;
            includeAttachments = (bool)AttachmentCheckBox.IsChecked;

            StatusViwer.Content= "";
            StatusBar.Value = 0;
            Thread migrationThread = new Thread(new ThreadStart(projectMigration));
            migrationThread.Start();

            
        }


        public void projectMigration()
        {
            CheckTestPlanTextBlock.Dispatcher.BeginInvoke(new Action(delegate()
            {
                CheckTestPlanTextBlock.Visibility = Visibility.Hidden;
            }));
            StatusBar.Dispatcher.BeginInvoke(new Action(delegate()
            {
                StatusBar.Visibility = Visibility.Visible;
            }));

            if (deletePlans)
            {
                foreach (ITestPlan destinationplan in destinationproj.TestPlans.Query("Select * From TestPlan"))
                {

                    System.Diagnostics.Debug.WriteLine("Deleting Plan - {0} : {1}", destinationplan.Id, destinationplan.Name);

                    destinationplan.Delete(DeleteAction.ForceDeletion); ;

                }
            }
            StatusViwer.Dispatcher.BeginInvoke(new Action(delegate()
            {
                StatusViwer.Content = StatusViwer.Content + "Test Plan Migration Started";
            }));

            CopyTestPlans();

            StatusBar.Dispatcher.BeginInvoke(new Action(delegate()
            {
                StatusBar.Visibility = Visibility.Hidden;
            }));

            StatusViwer.Dispatcher.BeginInvoke(new Action(delegate()
            {
                StatusViwer.Content = StatusViwer.Content + "\n Test Plan Migration Completed" ;
            }));
            CheckTestPlanTextBlock.Dispatcher.BeginInvoke(new Action(delegate()
            {
                CheckTestPlanTextBlock.Visibility = Visibility.Visible;
            }));
           
        }
        void CopyTestPlans()
        {

            int i = 1;
            int planCount = sourceproj.TestPlans.Query("Select * From TestPlan").Count;

            foreach (ITestPlan sourceplan in sourceproj.TestPlans.Query("Select * From TestPlan"))
            {

                System.Diagnostics.Debug.WriteLine("Plan - {0} : {1}", sourceplan.Id, sourceplan.Name);

                ITestPlan destinationplan = destinationproj.TestPlans.Create();               
                destinationplan.Name = sourceplan.Name;
                destinationplan.Description = sourceplan.Description;             
                destinationplan.StartDate = sourceplan.StartDate;
                destinationplan.EndDate = sourceplan.EndDate;
               
                    //to assign following fields you have to create same iterations, area paths, users in the target project.
                //destinationplan.AreaPath = sourceplan.AreaPath;
                //destinationplan.Iteration = sourceplan.Iteration;
                //destinationplan.Owner.= sourceplan.Owner;

                //destinationplan.State = sourceplan.State;
                

                destinationplan.Save();

                if (sourceplan.RootSuite != null && sourceplan.RootSuite.Entries.Count > 0)
                {
                    CopyTestSuites(sourceplan, destinationplan);
                }

                destinationplan.Save();

                StatusBar.Dispatcher.BeginInvoke(new Action(delegate()
                {
                    float progress = (float)i / (float)planCount;

                    StatusBar.Value = ((float)i / (float)planCount) * 100;
                }));

                StatusViwer.Dispatcher.BeginInvoke(new Action(delegate()
                {
                    StatusViwer.Content = StatusViwer.Content + "\nCopying " + destinationplan.Name;
                    StatusViwer.ScrollToBottom();

                }));
                i++;
            }  

        }

        void CopyTestSuites(ITestPlan sourceplan, ITestPlan destinationplan)
        {
            ITestSuiteEntryCollection suites = sourceplan.RootSuite.Entries;

            foreach (ITestSuiteEntry suite_entry in suites)
            {
                IStaticTestSuite suite = suite_entry.TestSuite as IStaticTestSuite;
                if (suite != null)
                {
                    IStaticTestSuite newSuite = destinationproj.TestSuites.CreateStatic();
                    newSuite.Title = suite.Title;
                    destinationplan.RootSuite.Entries.Add(newSuite); 
                    destinationplan.Save();

                    CopyTestCases(suite, newSuite);
                    if (suite.Entries.Count > 0)
                        CopySubTestSuites(suite, newSuite);
                }
            }

        }

        void CopySubTestSuites(IStaticTestSuite parentsourceSuite, IStaticTestSuite parentdestinationSuite)
        {
            ITestSuiteEntryCollection suitcollection = parentsourceSuite.Entries;
            foreach (ITestSuiteEntry suite_entry in suitcollection)
            {
                IStaticTestSuite suite = suite_entry.TestSuite as IStaticTestSuite;
                if (suite != null)
                {
                    IStaticTestSuite subSuite = destinationproj.TestSuites.CreateStatic();
                    subSuite.Title = suite.Title;
                    parentdestinationSuite.Entries.Add(subSuite);

                    CopyTestCases(suite, subSuite);

                    if (suite.Entries.Count > 0)
                        CopySubTestSuites(suite, subSuite);

                }     
            }
           
            
        }
        void CopyTestCases(IStaticTestSuite sourcesuite, IStaticTestSuite destinationsuite)
        {
            ITestCaseCollection dd=sourcesuite.AllTestCases;
            ITestSuiteEntryCollection suiteentrys = sourcesuite.TestCases;

            if(restoreChecked)
            {
                foreach (ITestSuiteEntry testcase in suiteentrys)
                {

                    int newWorkItemID =testcase.TestCase.WorkItem.Id;
                    ITestCase tc = destinationproj.TestCases.Find(newWorkItemID);
                    destinationsuite.Entries.Add(tc);

                }
            }

            else  if (migrationChecked && duplicateSharedSteps)
            {
                foreach (ITestSuiteEntry testcase in suiteentrys)
                {
                    ITestCase tc = destinationproj.TestCases.Create();
                    tc.Title = testcase.Title;
                    tc.Priority = testcase.TestCase.Priority;

                    foreach (ITestAction action in testcase.TestCase.Actions)
                    {

                        ISharedStep shared_step = null;
                        ISharedStepReference shared_ref = action as ISharedStepReference;
                        if (shared_ref != null)
                        {
                            shared_step = shared_ref.FindSharedStep();
                            foreach (ITestAction shr_action in shared_step.Actions)
                            {
                                ITestStep test_step = shr_action as ITestStep; ;
                                ITestStep destinationStep = tc.CreateTestStep();
                                destinationStep.Title = test_step.Title;
                                destinationStep.ExpectedResult = test_step.ExpectedResult;
                                tc.Actions.Add(destinationStep);
                            }

                        }
                        else
                        {
                            var test_step = action as ITestStep;
                            ITestStep destinationStep = tc.CreateTestStep();
                            destinationStep.Title = test_step.Title;
                            tc.Actions.Add(destinationStep);
                        }
                    }

                   tc.Save();
                   destinationsuite.Entries.Add(tc);
                }
            }
            else if (migrationChecked && !duplicateSharedSteps)
            {
                foreach (ITestSuiteEntry testcase in suiteentrys)
                {
                    ITestCase tc = destinationproj.TestCases.Create();
                    tc.Title = testcase.Title;
                    tc.Priority = testcase.TestCase.Priority;

                    tc.Save();
                    destinationsuite.Entries.Add(tc);
                }
            }

        }

        private void btn_connect_Click(object sender, RoutedEventArgs e)
        {

            TeamProjectPicker tpp = new TeamProjectPicker(TeamProjectPickerMode.SingleProject, false);
            tpp.ShowDialog();

            if (tpp.SelectedTeamProjectCollection != null)
            {
                this.sourceTFS = tpp.SelectedTeamProjectCollection;
                this.sourceStore = (WorkItemStore)sourceTFS.GetService(typeof(WorkItemStore));
                this.sourceProject = sourceStore.Projects[tpp.SelectedProjects[0].Name];
                 SourceProjectText.Text = string.Format("{0}/{1}",sourceTFS.Uri.ToString(),sourceProject.Name);


            }

            sourceproj = GetProject(sourceTFS, sourceProject.Name);
            
            
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            TeamProjectPicker tpp = new TeamProjectPicker(TeamProjectPickerMode.SingleProject, false);
            tpp.ShowDialog();

            if (tpp.SelectedTeamProjectCollection != null)
            {
                this.destinationTFS = tpp.SelectedTeamProjectCollection;
                this.destinationStore = (WorkItemStore)destinationTFS.GetService(typeof(WorkItemStore));
                this.destinationProject = destinationStore.Projects[tpp.SelectedProjects[0].Name];
                DestinationProjectText.Text = string.Format("{0}/{1}", destinationTFS.Uri.ToString(), destinationProject.Name);

            }
            destinationproj = GetProject(destinationTFS, destinationProject.Name);
        }

       
        private void MigrateTestSelectionCheckBox_Checked(object sender, RoutedEventArgs e)
        {
            
            OptionGroupPanel.IsEnabled = true;
            
        }

        private void MigrateTestSelectionCheckBox_Click(object sender, RoutedEventArgs e)
        {
            if (MigrateTestSelectionCheckBox.IsChecked == true)
            {
                OptionGroupPanel.IsEnabled = true;
                RestoreTestSelectionCheckBox.IsEnabled = false;
                RestoreTestSelectionCheckBox.IsChecked = false;

            }
            else
            {
                OptionGroupPanel.IsEnabled = false;
                RestoreTestSelectionCheckBox.IsEnabled = true;
                DeletePlansCheckBox.IsChecked = false;
                SharedStepCheckBox.IsChecked = false;
                AttachmentCheckBox.IsChecked = false;
            }
        }

        private void RestoreTestSelectionCheckBox_Click(object sender, RoutedEventArgs e)
        {
            if (RestoreTestSelectionCheckBox.IsChecked == true)
            {
                OptionGroupPanel.IsEnabled = false;
                MigrateTestSelectionCheckBox.IsChecked = false;
                DeletePlansCheckBox.IsChecked = false;
                SharedStepCheckBox.IsChecked = false;
                AttachmentCheckBox.IsChecked = false;
                MigrateTestSelectionCheckBox.IsEnabled = false;
            }
            else
            {
                MigrateTestSelectionCheckBox.IsEnabled = true;
            }
        }

        private void CheckTestPlanHyperLink_Click(object sender, RoutedEventArgs e)
        {
            TestPlanViewUI ts = new TestPlanViewUI();

            ts.tfs = this.destinationTFS;
            ts.targetProjectName = this.destinationProject.Name;
            ts.printProjectName();
            ts.Show();
        }

        

        
    }
}
